package ltd.smallwang.web;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil;
import com.alibaba.cola.dto.Response;
import com.alibaba.cola.dto.SingleResponse;
import com.alibaba.cola.exception.BizException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import ltd.smallwang.client.user.api.UserService;
import ltd.smallwang.client.user.dto.LoginNeedVerifyCodeQry;
import ltd.smallwang.client.user.dto.UserDto;
import ltd.smallwang.client.user.dto.UserLoginCmd;
import ltd.smallwang.client.user.dto.UserRegisterCmd;
import ltd.smallwang.infrastructure.exception.UserErrorCode;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 用户中心微服务
 *
 * @author justd
 */
@RestController
@Slf4j
@RequiredArgsConstructor
@RequestMapping("/user")
public class UserController {

  private final UserService userService;

  /**
   * 用户登录
   *
   * @return the single response
   */
  @PostMapping(value = "/v1/login", produces = MediaType.APPLICATION_JSON_VALUE,
      consumes = MediaType.APPLICATION_JSON_VALUE)
  public SingleResponse<SaTokenInfo> login(@Validated @RequestBody UserLoginCmd userLoginCmd,
      @RequestHeader(HttpHeaders.USER_AGENT) String userAgent) {
    UserAgent ua = UserAgentUtil.parse(userAgent);
    userService.login(userLoginCmd, ua.getPlatform());
    SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
    return SingleResponse.of(tokenInfo);
  }

  /**
   * 检查登录是否需要验证码
   *
   * @param loginNeedVerifyCodeQry the login need verify code qry
   * @return the single response
   */
  @PostMapping(value = "/v1/checkLoginNeedVerifyCode", produces = MediaType.APPLICATION_JSON_VALUE,
      consumes = MediaType.APPLICATION_JSON_VALUE)
  public SingleResponse<Boolean> checkLoginNeedVerifyCode(
      @Validated @RequestBody LoginNeedVerifyCodeQry loginNeedVerifyCodeQry) {
    return SingleResponse.of(userService.checkLoginNeedVerifyCode(loginNeedVerifyCodeQry));
  }

  /**
   * 用户注册
   *
   * @return the single response
   */
  @PostMapping(value = "/v1/register", produces = MediaType.APPLICATION_JSON_VALUE,
      consumes = MediaType.APPLICATION_JSON_VALUE)
  public Response register(@Validated @RequestBody UserRegisterCmd userRegisterCmd,
      @RequestHeader("User-Agent") String userAgent) {
    log.info("begin to register user");
    if (!userRegisterCmd.passwordIsStrong()) {
      log.warn("password is too weak");
      throw new BizException(UserErrorCode.PASSWORD_TOO_WEAK.getErrorCode(),
          UserErrorCode.PASSWORD_TOO_WEAK.getErrorMessage());
    }
    UserAgent ua = UserAgentUtil.parse(userAgent);
    userService.register(userRegisterCmd, ua.getPlatform());
    return Response.buildSuccess();
  }

  /**
   * 获取用户信息。 该接口使用GET请求，路径为/v1/getUserInfo，返回类型为JSON。 通过添加@SaCheckLogin注解，表明该接口需要用户登录后才能访问。
   *
   * @return SingleResponse<SaTokenInfo> 包含用户信息的单一响应对象。
   */
  @SaCheckLogin
  @GetMapping(value = "/v1/getUserInfo", produces = MediaType.APPLICATION_JSON_VALUE)
  public SingleResponse<UserDto> getUserInfo() {
    return SingleResponse.of(userService.getUserInfo());
  }

  /**
   * 实现用户登出功能。
   * <p>
   * 该接口使用GET请求，路径为/v1/logout，返回类型为JSON。
   * 调用此接口将触发用户的登出操作。
   *
   * @return 返回一个表示操作结果的Response对象，如果操作成功，则返回成功的响应。
   */
  @SaCheckLogin
  @GetMapping(value = "/v1/logout", produces = MediaType.APPLICATION_JSON_VALUE)
  public Response logout() {
    StpUtil.logout();
    return Response.buildSuccess();
  }
}
